#pragma once

#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/time.h>
#include <sys/select.h>
#include "Socket.hpp"
 
static const uint16_t default_port = 8080;

class SelectServer
{
public:
    SelectServer(uint16_t port = default_port){}

    bool Init()
    {
        _listen_sock.Socket();
        _listen_sock.Bind(_port);
        _listen_sock.Listen();

        return true;
    }

    void Start()
    {
        int listensock = _listen_sock.Fd();
        while(true)
        {
            // 不能直接accept, 检测并获取listen_sock上面的事件，新连接到来，等价于读事件就绪
            fd_set readfds;
            FD_ZERO(&readfds);
            FD_SET(listensock, &readfds);
            struct timeval timeout = {5, 0}; // 5s timeout
            int n = select(listensock+1, &readfds, nullptr, nullptr, &timeout);
            switch (n)
            {
            case -1:
                std::cerr << "select error, " << strerror(errno) << std::endl;
                break;
            case 0:
                std::cout << "select timeout, timeout: " << timeout.tv_sec << "." << timeout.tv_usec << std::endl;
                break;
            default:
                // 有事件就绪
                std::cout << "get a new link..." << std::endl;
                //HandlerEvent(readfds);
                break;
            }
            
        }
    }

    ~SelectServer()
    {
        _listen_sock.Close();
    }

private:
    uint16_t _port;
    Sock _listen_sock;
};
